package zhuzx.solution;

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JOptionPane;

import org.zhuzx.util.MicroUtil;

public class ProcUtil {
	
	public static void main(String[] args) {
		String targetStr = JOptionPane.showInputDialog("请输入需要生成的过程名：");
		Set<String> targets = new HashSet<String>(Arrays.asList(targetStr.split("\\s")));
		String procStr = JOptionPane.showInputDialog("请输入存储过程代码段：");
		int pacStart = procStr.indexOf("PACKAGE");
		pacStart = (pacStart == -1) ? procStr.indexOf("package") : pacStart;
		pacStart = pacStart + "PACKAGE".length() + 1;
		int pacEnd = procStr.indexOf(" ", pacStart);
		String pacName = procStr.substring(pacStart, pacEnd);
		int[] indexs = MicroUtil.findMatches(procStr, "\\sprocedure\\s|\\sPROCEDURE\\s");
		StringBuilder mappers = new StringBuilder();
		StringBuilder bexs = new StringBuilder();
		StringBuilder services = new StringBuilder();
		int count = 0;
		for (int i : indexs) {
			int bracketLeft = procStr.indexOf("(", i);
			String procName = procStr.substring(i+" procedure ".length(), bracketLeft).trim();
			String procCode = procName.substring(procName.lastIndexOf("_") + 1);
			if (!targets.contains(procCode)) continue;
			@SuppressWarnings("deprecation")
			int bracketRight = MicroUtil.searchMate(procStr, '(', ')', bracketLeft);
			if (bracketRight == -1) break;
			count++;
			String params = procStr.substring(bracketLeft+1, bracketRight);
			//--[^\r\n&&[^\n\r\f$]]*([\n\r\f$]|\r\n)
			//所谓的文本换行符\r\n无法被正则解析为单个符号
			params = params.replaceAll("\\s+\\w* *,", "}',");
			params = params.replaceAll("\\s{2,}", "\n");
			params = params.replaceAll(",\n--", ", --");
			//replaceFirst、replaceAll方法不能放入\与$符号
			params = params.replaceAll("v_|V_", "' {");
			params = params.replaceAll("' \\{", "\t\t\t' {");
			params = params.replaceAll(" \\{[pP]_.*?\\}", "");
			params = params.replaceFirst("' \\{", "\n\t\t\t' {");
			params = params.replaceFirst("''", "' {OP_CODE}'");
			params = params.replaceFirst("''", "#placeholder#");
			params = params.replaceFirst("''", "' {OP_SITE}'");
			params = params.replaceFirst("''", procCode);
			params = params.replaceFirst("#placeholder#", "''");
			params = params.replaceAll("\n--\\s*\n", "\n--");
			String commentReg = "\n[[\u4E00-\u9FA5\\w]&&[^\t]]";
			Pattern pat = Pattern.compile(commentReg);
			Matcher mat = pat.matcher(params);
			StringBuilder sb = new StringBuilder(params);
			while (mat.find()) {
				sb.replace(mat.start(), mat.end()-1, " ");
			}
			int[] paramIndexs = MicroUtil.findMatches(params, "' \\{");
			for (int j : paramIndexs) {
				sb.replace(j, j+3, "'${");
			}
			params = sb.toString();
			int[] rcIndexs = MicroUtil.findMatches(params, "\\s(rc1|RC1)\\s");
			int rc = (rcIndexs.length == 0) ? params.length() : rcIndexs[0];
			params = params.substring(0, rc);
			
			mappers.append("\n\t<select id=" + "\"" + procCode +
					"\" statementType=\"CALLABLE\" parameterType=\"hashmap\">");
			mappers.append("\n\t\t<![CDATA[");
			mappers.append("\n\t\t\tcall " + pacName + "." + procName + "(");
			mappers.append("\n" + params);
			mappers.append("\n\n\t\t\t" + "#{RC1,mode=OUT,jdbcType=CURSOR,"
					+ "javaType=java.sql.ResultSet,resultMap=ProcResultMap},");
			mappers.append("\n\t\t\t" + "#{RC2,mode=OUT,jdbcType=CURSOR,"
					+ "javaType=java.sql.ResultSet,resultMap=ProcResultMap})");
			mappers.append("\n\t\t]]>");
			mappers.append("\n\t" + "</select>\n");
			
			bexs.append("\n\t<bex bex_code=\"" + procCode + "\" bex_type=\"4\" "
					+ "page_mode=\"2\" bex_cate=\"1\" attr1=\"" + procCode + "\">");
			bexs.append("\n\t</bex>\n");
			
			services.append(
			"\n\t<service service_code=\"" + procCode + "\" service_name=\"\"\n" +
			"\t\t\tservice_type=\"1\" service_cate=\"1\" arrange_type=\"1\""
					+ " soap_enable=\"1\" attr1=\"\">\n" + 
			"\t\t<businesses>\n" + 
			"\t\t\t<service_business business_code=\"" + procCode + "\""
					+ " business_method=\"\"serial_no=\"1\"\n" + 
			"\t\t\t\t\tbusiness_name=\"\" business_type=\"1\" business_cate=\"1\" attr1=\"\" />\n" + 
			"\t\t</businesses>\n" + 
			"\t</service>\n");
		}
		
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		Clipboard clipboard = toolkit.getSystemClipboard();
		
		JOptionPane.showMessageDialog(null, "复制mapper代码到剪贴板");
		StringSelection ss = new StringSelection(mappers.toString());
		clipboard.setContents(ss, null);
		System.out.println(mappers);
		
		JOptionPane.showMessageDialog(null, "复制bex代码到剪贴板");
		ss = new StringSelection(bexs.toString());
		clipboard.setContents(ss, null);
		System.out.println(bexs);
		
		JOptionPane.showMessageDialog(null, "复制service代码到剪贴板");
		ss = new StringSelection(services.toString());
		clipboard.setContents(ss, null);
		System.out.println(services);
		
		System.out.println(">>>>一共" + count + "个");
	}
	
}
